/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.swe.chums.beans;

import com.swe.chums.dao.RatingDao;
import com.swe.chums.dao.TagDao;
import com.swe.chums.dao.TagTypeDao;
import com.swe.chums.dao.UserActivityDao;
import com.swe.chums.dao.UserDao;
import com.swe.chums.dao.UserFavoriteDao;
import com.swe.chums.dao.UserTagTypeDao;
import com.swe.chums.dao.WebResourceDao;
import com.swe.chums.dao.exceptions.LessonsDaoException;
import com.swe.chums.dao.exceptions.RatingDaoException;
import com.swe.chums.dao.exceptions.TagDaoException;
import com.swe.chums.dao.exceptions.TagTypeDaoException;
import com.swe.chums.dao.exceptions.UserActivityDaoException;
import com.swe.chums.dao.exceptions.UserDaoException;
import com.swe.chums.dao.exceptions.UserFavoriteDaoException;
import com.swe.chums.dao.exceptions.UserTagTypeDaoException;
import com.swe.chums.dao.exceptions.WebResourceDaoException;
import com.swe.chums.dao.factory.DaoFactory;
import com.swe.chums.dao.model.Lessons;
import com.swe.chums.dao.model.Tag;
import com.swe.chums.dao.model.TagType;
import com.swe.chums.dao.model.User;
import com.swe.chums.dao.model.UserActivity;
import com.swe.chums.dao.model.UserFavorite;
import com.swe.chums.dao.model.UserFavoritePk;
import com.swe.chums.dao.model.UserPk;
import com.swe.chums.dao.model.UserTagType;
import com.swe.chums.dao.model.WebResource;
import com.swe.chums.dao.model.WebResourcePk;
import com.swe.chums.utils.CommonUtils;
import com.swe.chums.utils.UserActivityTypeEnum;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.logging.Level;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.apache.log4j.Logger;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.data.FilterEvent;

/**
 *
 * @author cilingir
 */
@ManagedBean(name = "userBean")
@ViewScoped
public class UserBean implements Serializable{

    private static Logger log = Logger.getLogger(UserBean.class);
    private User user;
    private String password2;
    private WebResource toBeRemovedMyCourse;
    private ArrayList<WebResource> myCourses = new ArrayList<WebResource>();
    private ArrayList<WebResource> recommendedCourses = new ArrayList<WebResource>();
    
    public UserBean() {
        FacesContext context = FacesContext.getCurrentInstance();
        UserFavoriteDao ufDao = DaoFactory.createUserFavoriteDao();
        LoginBean loginBean = (LoginBean) context.getExternalContext().getSessionMap().get("loginBean");
        
        TagDao tDao = DaoFactory.createTagDao();
        HashMap<String, Integer> tagIdList = new HashMap<String, Integer>();
                     
        TagTypeDao ttDao = DaoFactory.createTagTypeDao();
        if (loginBean!=null && loginBean.isLoggedIn()) {
            try {
                myCourses.clear();
                int currentUserID = ((LoginBean) context.getExternalContext().getSessionMap().get("loginBean")).getUser().getId();
                ArrayList<UserFavorite> ufList = (ArrayList<UserFavorite>) ufDao.findWhereUserIdEquals(currentUserID);
                WebResourceDao wrDao = DaoFactory.createWebResourceDao();
                for (int i=0; i<ufList.size(); i++) {
                    int webResourceId = ufList.get(i).getWebResourceId();
                    WebResource wr = wrDao.findWhereIdEquals(webResourceId).get(0);
                     RatingDao rDao = DaoFactory.createRatingDao();
        
                                    int averageRatingInt = wr.getAverageRating().intValue();
                                    wr.setAverageRatingInt(averageRatingInt);
                                    
                                    wr.setRatingCount(rDao.findWhereWebResourceIdEquals(wr.getId()).size());
                                    ArrayList<Tag> wTags = (ArrayList<Tag>) tDao.findWhereWebResourceIdEquals(wr.getId());
                                    String tags2 = "";
                                    for (int k=0; k<wTags.size(); k++) {
                                        tags2 += ttDao.findWhereIdEquals(wTags.get(k).getTagTypeId()).get(0).getName() + " ";
                                    }
                                    wr.setTagsText(tags2);
                                    wr.setFavorited(getIfUserFavoritedCourse(wr.getId()));
                                    
                                    wr.setHitCount(wr.getHitCount()+1);
                                    ArrayList<Lessons> lessons = (ArrayList<Lessons>) DaoFactory.createLessonsDao().findWhereWebresourceIdEquals(wr.getId());
                                
                                
                                wr.setLessons(lessons);
                                    
                    myCourses.add(wr);
                    
                    // Favorite courses recommendation
                    ArrayList<Tag> tags = (ArrayList<Tag>) tDao.findWhereWebResourceIdEquals(webResourceId);
                    for (int j=0; j<tags.size(); j++) {
                        tagIdList.put(tags.get(j).getTagTypeId() + "", tags.get(j).getTagTypeId());
                    }
                    
                }
                
                // Viewed courses recommendation
                UserActivityDao uaDao = DaoFactory.createUserActivityDao();
                ArrayList<UserActivity> uaList = (ArrayList<UserActivity>) uaDao.findWhereUserAndActivityEquals(currentUserID, UserActivityTypeEnum.VIEW.getId());
                for (int i=0; i<uaList.size(); i++) {
                    ArrayList<Tag> tags = (ArrayList<Tag>) tDao.findWhereWebResourceIdEquals(uaList.get(i).getWebResourceId());
                    for (int j=0; j<tags.size(); j++) {
                        tagIdList.put(tags.get(j).getTagTypeId() + "", tags.get(j).getTagTypeId());
                    }
                }
                
                // Rated courses recommendation
                ArrayList<UserActivity> uaRateList = (ArrayList<UserActivity>) uaDao.findWhereUserAndActivityEquals(currentUserID, UserActivityTypeEnum.RATE.getId());
                for (int i=0; i<uaRateList.size(); i++) {
                    ArrayList<Tag> tags = (ArrayList<Tag>) tDao.findWhereWebResourceIdEquals(uaRateList.get(i).getWebResourceId());
                    for (int j=0; j<tags.size(); j++) {
                        tagIdList.put(tags.get(j).getTagTypeId() + "", tags.get(j).getTagTypeId());
                    }
                }
                
                // Searched courses recommendation
                ArrayList<UserActivity> uaSearchList = (ArrayList<UserActivity>) uaDao.findWhereUserAndActivityEquals(currentUserID, UserActivityTypeEnum.SEARCH.getId());
                for (int i=0; i<uaSearchList.size(); i++) {
                    ArrayList<TagType> tagTypes = (ArrayList<TagType>) ttDao.findWhereNameEquals(uaSearchList.get(i).getActivityValue());
                    for (int j=0; j<tagTypes.size(); j++) {
                        ArrayList<Tag> tags = (ArrayList<Tag>) tDao.findWhereTagTypeIdEquals(tagTypes.get(j).getId());
                        for (int k=0; k<tags.size(); k++) {
                            tagIdList.put(tags.get(k).getTagTypeId() + "", tags.get(k).getTagTypeId());
                        }
                    }
                }
                
                // Commented courses recommendation
                ArrayList<UserActivity> uaCommentList = (ArrayList<UserActivity>) uaDao.findWhereUserAndActivityEquals(currentUserID, UserActivityTypeEnum.COMMENT.getId());
                for (int i=0; i<uaCommentList.size(); i++) {
                    ArrayList<Tag> tags = (ArrayList<Tag>) tDao.findWhereWebResourceIdEquals(uaCommentList.get(i).getWebResourceId());
                    for (int j=0; j<tags.size(); j++) {
                        tagIdList.put(tags.get(j).getTagTypeId() + "", tags.get(j).getTagTypeId());
                    }
                }
                
                
                // User registered tags
                UserTagTypeDao uttDao = DaoFactory.createUserTagTypeDao();
                ArrayList<UserTagType> userTagTypeList = (ArrayList<UserTagType>) uttDao.findWhereUserIdEquals(currentUserID);
                for (int i=0; i<userTagTypeList.size(); i++) {
                    tagIdList.put(userTagTypeList.get(i).getTagId() + "", userTagTypeList.get(i).getTagId());
                }
                
                String inStatement = " (";
                Iterator it = tagIdList.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry pairs = (Map.Entry)it.next();
                    inStatement += pairs.getKey() + ",";
                    System.out.println(pairs.getKey() + " = " + pairs.getValue());
                    it.remove(); // avoids a ConcurrentModificationException
                }
                inStatement = inStatement.substring(0, inStatement.length()-1);
                inStatement +=") ";
                recommendedCourses.clear();
                
                recommendedCourses = (ArrayList<WebResource>) wrDao.getRecommendedWebResources(inStatement);
                // get user favorite courses
                // get tags ids 
                // o tag idsi olan course idleri çek
                // order in rating
                
            } catch (LessonsDaoException ex) {
                java.util.logging.Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, null, ex);
            } catch (RatingDaoException ex) {
                java.util.logging.Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, null, ex);
            } catch (UserTagTypeDaoException ex) {
                
            } catch (UserActivityDaoException ex) {
                
            } catch (UserFavoriteDaoException ex) {
                
            } catch (WebResourceDaoException ex) {
                
            } catch (TagDaoException ex)  {
                
            } catch (TagTypeDaoException ex) {
                
            }
                
        }
        
    }
    
    
    /**
     * Get if the user favorited the course
     * 
     * @param id
     * @return 
     */
    private boolean getIfUserFavoritedCourse(int id) {
        FacesContext context = FacesContext.getCurrentInstance();
        LoginBean loginBean = (LoginBean) context.getExternalContext().getSessionMap().get("loginBean");
        UserFavoriteDao ufDao = DaoFactory.createUserFavoriteDao();
        boolean result = false;
        if (loginBean!=null && loginBean.isLoggedIn()) {
            int currentUserID = ((LoginBean) context.getExternalContext().getSessionMap().get("loginBean")).getUser().getId();
            try {
                if (ufDao.findWhereUserIdAndWebResourceIdEquals(currentUserID, id).size()>0) {
                    result = true;
                }
            } catch (Exception ex) {
                
            }
            
        }
        return result;
    }
    
    /**
     * Register user
     * 
     * @return 
     */
    public String register() {
        
        log.debug("[UserBean.register] - started");
        FacesContext context = FacesContext.getCurrentInstance();
        String text;
        
        try {
            
            if (user.getName() != null && !user.getName().equals("")) {
                user.setName(user.getName().trim());
            } else {
                user.setName("");
            }
            
            if (user.getUsername() != null && !user.getUsername().equals("")) {
                user.setUsername(user.getUsername().trim());
            } else {
                user.setUsername("");
            }
            
            if (user.getPassword() != null && !user.getPassword().equals("")) {
                user.setPassword(user.getPassword().trim());
            } else {
                user.setPassword("");
            }
            
            if (password2 != null && !password2.equals("")) {
                password2 = password2.trim();
            } else {
                password2 = "";
            }
            
            if (user.getEmail() != null && !user.getEmail().equals("")) {
                user.setEmail(user.getEmail().trim());
            } else {
                user.setEmail("");
            }
            
            
            if (user.getName().equals("")) {
                log.error("[UserBean.register] - name is empty");
                text = "Name is empty";
                context.addMessage("form:name", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAlphaNumerical(user.getName())) {
                log.error("[UserBean.register] - user's name is not in allowed format: " + user.getName());
                text = "Name must be alphanumerical";
                context.addMessage("form:name", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(user.getName(), 60)) {
                log.error("[UserBean.register] - user's name is not in allowed length: " + user.getName());
                text = "Name can't be longer than 60 characters";
                context.addMessage("form:name", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            }
            
            if (user.getUsername().equals("")) {
                log.error("[UserBean.register] - username is empty");
                text = "Username is empty";
                context.addMessage("form:username", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAlphaNumerical(user.getUsername())) {
                log.error("[UserBean.register] - user's username is not in allowed format: " + user.getUsername());
                text = "Username must be alphanumerical";
                context.addMessage("form:username", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(user.getUsername(), 40)) {
                log.error("[UserBean.register] - user's username is not in allowed length: " + user.getUsername());
                text = "Username can't be longer than 40 characters";
                context.addMessage("form:username", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else {
                try {
                    log.debug("[UserBean.register] - user dao created");
                    ArrayList<User> usernameList = (ArrayList<User>) DaoFactory.createUserDao().findWhereUsernameEquals(user.getUsername());

                    if (usernameList != null && usernameList.size() > 0) {
                        log.error("[UserBean.register] - username exists: " + user.getUsername());
                        text = "Username exists";
                        context.addMessage("form:username", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
                    }
                } catch (UserDaoException ex) {
                    log.error("[UserBean.register] - error while retrieving values from DB, message is:  " + ex.getMessage());
                    context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "DB error"));
                    return null;
                }
            }
            
            if (user.getEmail().equals("")) {
                log.error("[UserBean.register] - email is empty");
                text = "Email is empty";
                context.addMessage("form:email", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!user.getEmail().matches("[\\w\\.-]*[a-zA-Z0-9_]@[\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]")) {
                log.error("[UserBean.register] - email is not in right format: " + user.getEmail());
                text = "Email is not in correct format";
                context.addMessage("form:email", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(user.getEmail(), 70)) {
                log.error("[UserBean.register] - email is not in allowed length: " + user.getEmail());
                text = "Email can't be  longer than 70";
                context.addMessage("form:email", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else {
                try {
                    log.info("[UserBean.register] - user dao created");
                    ArrayList<User> emailList = (ArrayList<User>) DaoFactory.createUserDao().findWhereEmailEquals(user.getEmail());

                    if (emailList != null && emailList.size() > 0) {
                        log.error("[UserBean.register] - email exists: " + user.getEmail());
                        text = "Email exists";
                        context.addMessage("form:email", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
                    }
                } catch (UserDaoException ex) {
                    log.error("[UserBean.register] - error while retrieving values from DB, message is:  " + ex.getMessage());
                    context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "DB error"));
                    return null;
                }
            }
            
            if (user.getPassword().equals("")) {
                log.error("[UserBean.register] - password is empty");
                text = "Password is empty";
                context.addMessage("form:password", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAlphaNumerical(user.getPassword())) {
                log.error("[UserBean.register] - user's password is not in allowed format: " + user.getPassword());
                text = "Password must be alphanumerical";
                context.addMessage("form:password", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(user.getPassword(), 40)) {
                log.error("[UserBean.register] - password is not in allowed length: " + user.getPassword());
                text = "Password can't be  longer than 40";
                context.addMessage("form:password", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            }
            
            if (!user.getPassword().equals(password2)) {
                log.error("[UserBean.register] - passwords do not match: " + user.getPassword() + ", " + password2);
                text = "Passwords do not match";
                context.addMessage("form:password2", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            }
            
            if (context.getMessageList().size() > 0) {
                log.error("[UserBean.register] - there are errors with the form");
                return null;
            } else {
                log.info("[UserBean.register] - adding user: " + user.getUsername());

                User currentUser = new User();
                currentUser.setUsername(user.getUsername());
                currentUser.setName(user.getName());
                currentUser.setEmail(user.getEmail());
                currentUser.setUserTypeId(1);
                currentUser.setRegisterDate(new Date());                
                try {
                    currentUser.setPassword(CommonUtils.convertMd5(user.getPassword()));
                } catch (NoSuchAlgorithmException ex) {
                    log.error("[UserBean.register] - error while converting string to md5, message is:" + ex.getMessage());
                    context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "General error with MD5"));
                    return null;
                }
                
                // Insert user
                DaoFactory.createUserDao().insert(currentUser);
                log.info("[UserBean.addUser] - user inserted to db: " + user.getUsername());

                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "BİLGİ", "Account created"));
                context.getExternalContext().getFlash().setKeepMessages(true);
                return "index.xhtml?faces-redirect=true";

            }
            
        } catch (Exception ex) {
            log.error("[UserBean.register] - General exception, message is:  " + ex.getMessage());
            context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "General error"));
            return null;
        }
    }
    
    /**
     * Reset password
     * 
     * @return 
     */
    public String resetPass() {
        
        log.debug("[UserBean.resetPass] - started");
        FacesContext context = FacesContext.getCurrentInstance();
        String text = "ERROR";
        String errorText = "ERROR";
        
        // Check if email is valid 
        if (user.getEmail().trim().equals("")) {
            log.error("[UserBean.resetPass] - email is empty");
            text = "Email is empty";
            context.addMessage("form:email", new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
        } else if (!user.getEmail().matches("[\\w\\.-]*[a-zA-Z0-9_]@[\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]")) {
            log.error("[UserBean.resetPass] - email is not in right format: " + user.getEmail());
            text = "Email is not in correct format";
            context.addMessage("form:email", new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
        } else {
            try {
                ArrayList<User> emailList = (ArrayList<User>) DaoFactory.createUserDao().findWhereEmailEquals(user.getEmail());
                log.debug("[UserBean.resetPass] - user dao created");
                if ((emailList != null && emailList.isEmpty()) || (emailList == null)) {
                    log.error("[UserBean.resetPass] - email doesn't exist: " + user.getEmail());
                    text = "Email does not exist";
                    context.addMessage("form:email", new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
                }
            } catch (UserDaoException ex) {
                log.error("[UserBean.resetPass] - error while retrieving values from DB, message is:  " + ex.getMessage());
                text = "General DB error";
                context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
                return null;
            }
        }

        if (context.getMessageList().size() > 0) {
            log.error("[UserBean.resetPass] - there are errors with the form");
            return null;
        } else {
            String to = user.getEmail();
            String resetPassword = CommonUtils.generatePass(8);
            log.info("[UserBean.resetPass] - new password generated: " + resetPassword);
            UserDao userDao = DaoFactory.createUserDao();
            User currentUser;
            
            try {
                currentUser = userDao.findWhereEmailEquals(user.getEmail()).get(0);
                // Send mail
                log.info("[UserBean.resetPass] - sending reset mail to the user: " + user.getEmail());
                // 1: reset mail
                CommonUtils.sendMail(to, currentUser.getUsername(), resetPassword, "CHUMS - Password Reset", "Your new password is: " + resetPassword);
                log.info("[UserBean.resetPass] - reset mail sent to the user: " + user.getEmail());
                
                currentUser.setPassword(CommonUtils.convertMd5(resetPassword));
                UserPk userPk = new UserPk(currentUser.getId());
                userDao.update(userPk, currentUser);
                log.info("[UserBean.resetPass] - user pass updated in db for the user: " + currentUser.getId());
                
            } catch (NoSuchAlgorithmException ex) {
                log.error("[UserBean.resetPass] - error while converting string to md5, message is:" + ex.getMessage());
                text = "General error";
                context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
                return null;
            } catch (UserDaoException ex) {
                log.error("[UserBean.resetPass] - error while retrieving values from DB, message is:  " + ex.getMessage());
                text = "DB error";
                context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
                return null;
            } catch (Exception ex) {
                log.error("[UserBean.resetPass] - sending email has encountered an error");
                context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, ex.getMessage()));
                return null;
            }

            text = "Your new password is sent to your email";
            String infoText = "INFO";
            context.addMessage("null", new FacesMessage(FacesMessage.SEVERITY_INFO, infoText, text));
            context.getExternalContext().getFlash().setKeepMessages(true);
            return "index.xhtml?faces-redirect=true";
        }
        
    }
    
    /**
     * Remove my course
     * 
     */
    public void removeMyCourse() {
        log.debug("[AdminBean.removeWebResource] - started");
        FacesContext context = FacesContext.getCurrentInstance();
        String text;
        String errorText = "ERROR";
        
        if (toBeRemovedMyCourse != null) {
            
            UserFavoriteDao ufDao = DaoFactory.createUserFavoriteDao();
            UserFavoritePk ufpk = new UserFavoritePk();
            int id = toBeRemovedMyCourse.getId();
            
            
            try {
                ufpk.setId(ufDao.findWhereWebResourceIdEquals(id).get(0).getId());
                ufDao.delete(ufpk);
                myCourses.remove(toBeRemovedMyCourse);
                
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "INFO", "Succesfully removed"));

            } catch (UserFavoriteDaoException ex) {
                log.error("[AdminBean.removeWebResource] - error while deleting values from DB, message is:  " + ex.getMessage());
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, "General DB Error"));
            }
            

        } else {
            // You shouldnt be here!
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, "Not selected"));
        }
    }
    
    /**
     * Filter event handler
     *
     * @param event
     * @return
     */
    public Map<String, String> onFilterMyCourses(FilterEvent event) {

        log.debug("[AdminBean.onFilterAllUsers] started");
        Map<String, String> filters;
        DataTable table = (DataTable) event.getSource();

//        List<User> obj = table.getFilteredData();
//        if (obj != null) {
//            table.getFilteredData().remove(obj);
//        }
        filters = table.getFilters();
        filters.clear();

        return filters;
    }
    
    /**
     * Row edit event for user datatable
     *
     */
    public void onEditRow(RowEditEvent event) {
        log.debug("[UserBean.onEditRow] started");
        FacesContext context = FacesContext.getCurrentInstance();
        String text;
        String errorText = "ERROR";
        try {
            UserDao userDao = DaoFactory.createUserDao();
            User user = (User) event.getObject();
            UserPk userPk = new UserPk(user.getId());
            User oldUser = userDao.findByPrimaryKey(userPk);

            log.debug("[UserBean.onEditRow], userID to be editted: " + user.getId());

            // validation ifs
            String email = user.getEmail().trim();
            String name = user.getName().trim();
            String username = user.getUsername().trim();
            
            if (name.equals("")) {
                log.error("[UserBean.onEditRow] - name is empty");
                text = "Name is empty";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAlphaNumerical(name)) {
                log.error("[UserBean.onEditRow] - user's name is not in allowed format: " + name);
                text = "Name must be alphanumerical";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(name, 60)) {
                log.error("[UserBean.onEditRow] - user's name is not in allowed length: " + name);
                text = "Name can't be longer than 60 characters";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            }
            
            if (username.equals("")) {
                log.error("[UserBean.onEditRow] - username is empty");
                text = "Username is empty";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAlphaNumerical(username)) {
                log.error("[UserBean.onEditRow] - user's username is not in allowed format: " + username);
                text = "Username must be alphanumerical";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(username, 40)) {
                log.error("[UserBean.onEditRow] - user's username is not in allowed length: " + username);
                text = "Username can't be longer than 40 characters";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else {
                if (!username.equals(oldUser.getUsername())) {
                    try {
                        log.debug("[UserBean.onEditRow] - user dao created");
                        ArrayList<User> usernameList = (ArrayList<User>) DaoFactory.createUserDao().findWhereUsernameEquals(username);

                        if (usernameList != null && usernameList.size() > 0) {
                            log.error("[UserBean.onEditRow] - username exists: " + username);
                            text = "Username exists";
                            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
                        }
                    } catch (UserDaoException ex) {
                        log.error("[UserBean.onEditRow] - error while retrieving values from DB, message is:  " + ex.getMessage());
                        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "DB error"));
                    }
                }
            }
            
            if (email.equals("")) {
                log.error("[UserBean.onEditRow] - email is empty");
                text = "Email is empty";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!email.matches("[\\w\\.-]*[a-zA-Z0-9_]@[\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]")) {
                log.error("[UserBean.onEditRow] - email is not in right format: " + email);
                text = "Email is not in correct format";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(email, 70)) {
                log.error("[UserBean.onEditRow] - email is not in allowed length: " + email);
                text = "Email can't be  longer than 70";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else {
                if (!email.equals(oldUser.getEmail())) {
                    try {
                        log.info("[UserBean.onEditRow] - user dao created");
                        ArrayList<User> emailList = (ArrayList<User>) DaoFactory.createUserDao().findWhereEmailEquals(email);

                        if (emailList != null && emailList.size() > 0) {
                            log.error("[UserBean.onEditRow] - email exists: " + email);
                            text = "Email exists";
                            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
                        }
                    } catch (UserDaoException ex) {
                        log.error("[UserBean.onEditRow] - error while retrieving values from DB, message is:  " + ex.getMessage());
                        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "DB error"));
                    }
                }
            }
            
            if (context.getMessageList().size() > 0) {
                // Rollback on error
                user.setName(oldUser.getName());
                user.setEmail(oldUser.getEmail());
                user.setUsername(oldUser.getUsername());

                log.error("[UserBean.onEditRow] - there are errors with the form");
                text = "There are errors with the form";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
            } else {
                // Update user
                DaoFactory.createUserDao().update(userPk, user);
                log.debug("[UserBean.onEditRow] - no errors with the form, user dao created and updated with the id: " + user.getId());

                log.debug("[UserBean.onEditRow] - refreshing user chart");

                String updateText = "Updated successfully";
                String infoText = "INFO";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, infoText, updateText));

                // Record user action
                LoginBean loginBean = (LoginBean) context.getExternalContext().getSessionMap().get("loginBean");
                loginBean.setUser(user);
                
            }
        } catch (UserDaoException ex) {
            log.error("[UserBean.onEditRow] - exception message: " + ex.getMessage());
            text = "General error with DB";
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
        }
    }
    
    /**
     * Change password
     * 
     */
    public void changePassword() {
        
        log.debug("[UserBean.changePassword] - started");
        FacesContext context = FacesContext.getCurrentInstance();
        String text;
        String errorText = "ERROR";
        
        try {
            String password = user.getPassword().trim();
            password2 = password2.trim();
            
            
            if (password.equals("")) {
                log.error("[UserBean.changePassword] - password is empty");
                text = "Password is empty";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAlphaNumerical(password)) {
                log.error("[UserBean.changePassword] - user's password is not in allowed format: " + password);
                text = "Password must be alphanumerical";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(password, 40)) {
                log.error("[UserBean.changePassword] - password is not in allowed length: " + password);
                text = "Password can't be  longer than 40";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            }
            
            if (!password.equals(password2)) {
                log.error("[UserBean.changePassword] - passwords do not match: " + password + ", " + password2);
                text = "Passwords do not match";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            }
            
            // Record user action
            LoginBean loginBean = (LoginBean) context.getExternalContext().getSessionMap().get("loginBean");
            
            if (context.getMessageList().size() > 0) {
                log.error("[UserBean.changePassword] - There are errors with the form");
            } else {
                // Dao update
                UserPk userPk = new UserPk(loginBean.getUser().getId());
                User user = loginBean.getUser();
                try {
                    user.setPassword(CommonUtils.convertMd5(password));
                } catch (NoSuchAlgorithmException ex) {
                    log.error("[UserBean.changePassword] - error while converting string to md5, message is:" + ex.getMessage());
                    text = "General error with MD5";
                    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
                }
                try {
                    DaoFactory.createUserDao().update(userPk, user);
                    loginBean.setUser(user);
                    log.info("[UserBean.changePassword] - change pasword is successfull for the user: "+user.getId());

                    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "INFO", "Password updated successfully"));
                    
                } catch (UserDaoException ex) {
                    log.error("[UserBean.changePassword] - error while retrieving values from DB, message is:  " + ex.getMessage());
                    text = "General error with DB";
                    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
                }

            }
        } catch (Exception ex) {
            
        }
        
    }
    
    /**
     * Remove user
     * 
     * @return 
     */
    public String removeUser() {
        
        log.debug("[UserBean.removeUser] - started");
        FacesContext context = FacesContext.getCurrentInstance();
        String text;
        String errorText = "ERROR";
        String returnUrl = "";
        try {
            // Record user action
            LoginBean loginBean = (LoginBean) context.getExternalContext().getSessionMap().get("loginBean");
            
            // Dao update
            UserPk userPk = new UserPk(loginBean.getUser().getId());
            User user = loginBean.getUser();
            
            try {
                DaoFactory.createUserDao().delete(userPk);
                returnUrl = loginBean.logout();
            } catch (UserDaoException ex) {
                log.error("[UserBean.removeUser] - error while retrieving values from DB, message is:  " + ex.getMessage());
                text = "General error with DB";
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, errorText, text));
            }
        } catch (Exception ex) {
            
        }
        
        return returnUrl;
        
    }
    
    
    /*----Getter Setters---- */

    public User getUser() {
        if (user == null) {
            user = new User();
        }
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getPassword2() {
        return password2;
    }

    public void setPassword2(String password2) {
        this.password2 = password2;
    }

    public WebResource getToBeRemovedMyCourse() {
        return toBeRemovedMyCourse;
    }

    public void setToBeRemovedMyCourse(WebResource toBeRemovedMyCourse) {
        this.toBeRemovedMyCourse = toBeRemovedMyCourse;
    }

    public ArrayList<WebResource> getMyCourses() {
        return myCourses;
    }

    public void setMyCourses(ArrayList<WebResource> myCourses) {
        this.myCourses = myCourses;
    }

    public ArrayList<WebResource> getRecommendedCourses() {
        return recommendedCourses;
    }

    public void setRecommendedCourses(ArrayList<WebResource> recommendedCourses) {
        this.recommendedCourses = recommendedCourses;
    }

    
}
